#ifndef CLIB_CLIB_CONTAINER_SINGLE_LINKED_LIST_H
#define CLIB_CLIB_CONTAINER_SINGLE_LINKED_LIST_H

/**
 * 提供一个单向链表容器，该单向链表可以存储使用者提供的数据指针，
 * 并且该数据指针的内存空间的创建与释放交由使用者管理。
 *
 * 注意：该库线程不安全，如多线程执行请自行加锁
 *
 * list: |-----| => |------| => ... => |------| => |------|
 *        head       first                           last
 */

#include "../../base/clib_base.h"

CLIB_CPLUS_SUPPORT_START

/**
 * 单向链表对象
 */
struct clib_container_single_linked_list;

/**
 * 单向链表元素项对象
 */
struct clib_container_single_linked_list_entry;


/**
 * 创建一个单向链表
 * @return
 *      成功 单链表对象指针、
 *      失败 NULL
 */
struct clib_container_single_linked_list *
clib_container_single_linked_list_create();


/**
 * 销毁一个单向链表
 * 如果当前元素个数不为0 则无法销毁
 * 由于用户添加的数据指针需要用户手动释放，所以销毁单链表之前，需要手动将元素全部删除
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_destroy(
        struct clib_container_single_linked_list *list);

/**
 * 获取当前元素个数
 * @param list 链表对象
 * @return
 *      成功 当前元素个数
 */
size_t
clib_container_single_linked_list_get_current_size(
        struct clib_container_single_linked_list *list);

/**
 * 获取首元素
 * @param list 链表对象
 * @return
 *      成功 首元素指针
 *      失败 NULL
 */
struct clib_container_single_linked_list_entry *
clib_container_single_linked_list_get_first(
        struct clib_container_single_linked_list *list);


/**
 * 获取尾元素
 * @param list 链表对象
 * @return
 *      成功 尾元素指针
 *      失败 NULL
 */
struct clib_container_single_linked_list_entry *
clib_container_single_linked_list_get_last(
        struct clib_container_single_linked_list *list);

/**
 * 在某个元素之后插入数据
 * @param list 链表对象
 * @param entry 元素指针
 * @param data 插入的数据指针
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_insert_next(
        struct clib_container_single_linked_list *list,
        struct clib_container_single_linked_list_entry *entry,
        void *data);

/**
 * 在某个元素之前插入数据
 * @param list 链表对象
 * @param entry 元素指针
 * @param data 插入的数据指针
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_insert_pre(
        struct clib_container_single_linked_list *list,
        struct clib_container_single_linked_list_entry *entry,
        void *data);

/**
 * 在最前面插入元素
 * @param list 链表对象
 * @param data 插入的数据指针
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_insert_first(
        struct clib_container_single_linked_list *list,
        void *data);

/**
 * 在最后面插入元素
 * @param list 链表对象
 * @param data 插入的数据指针
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_insert_last(
        struct clib_container_single_linked_list *list,
        void *data);

/**
 * 删除首元素
 * @param list 链表对象
 * @return
 *      成功 删除之后的数据指针，需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_delete_first(
        struct clib_container_single_linked_list *list);


/**
 * 删除指定元素
 * @param list 链表对象
 * @param entry 要删除的元素
 * @return
 *      成功 删除之后的数据指针，需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_delete(
        struct clib_container_single_linked_list *list,
        struct clib_container_single_linked_list_entry *entry);


/**
 * 删除尾元素
 * @param list 链表对象
 * @return
 *      成功 删除之后的数据指针，需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_delete_last(
        struct clib_container_single_linked_list *list);


/**
 * 替换指定元素
 * @param list 链表对象
 * @param entry 要替换的元素
 * @param new_data 替换后的数据指针
 * @return
 *      成功 替换之前的数据指针 需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_replace(
        struct clib_container_single_linked_list *list,
        struct clib_container_single_linked_list_entry *entry,
        void *new_data);

/**
 * 替换首元素
 * @param list 链表对象
 * @param new_data 要替换的新数据
 * @return
 *      成功 替换之前的数据指针 需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_replace_first(
        struct clib_container_single_linked_list *list,
        void *new_data);


/**
 * 替换尾元素
 * @param list 链表对象
 * @param new_data 要替换的新数据
 * @return
 *      成功 替换之前的数据指针 需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_replace_last(
        struct clib_container_single_linked_list *list,
        void *new_data);


/**
 * 通过索引获取元素
 * @param list 链表对象
 * @param index 查找的索引
 * @return
 *      成功 返回查找到的元素
 *      失败 NULL
 */
struct clib_container_single_linked_list_entry *
clib_container_single_linked_list_get_entry_by_index(
        struct clib_container_single_linked_list *list,
        int index);


/**
 * 通过索引删除元素
 * @param list 链表对象
 * @param index 删除的索引
 * @return
 *      成功 返回删除的数据指针 需要用户手动释放
 *      失败 NULL
 */
void *
clib_container_single_linked_list_delete_entry_by_index(
        struct clib_container_single_linked_list *list,
        int index);


/**
 * 将元素1移动到元素2之后
 * @param list 链表对象
 * @param entry1 元素1
 * @param entry2 元素2
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_moveto_next(
        struct clib_container_single_linked_list *list,
        struct clib_container_single_linked_list_entry *entry1,
        struct clib_container_single_linked_list_entry *entry2);


/**
 * 将元素1移动到元素2之前
 * @param list 链表对象
 * @param entry1 元素1
 * @param entry2 元素2
 * @return
 *      成功 0
 *      失败 非0
 */
int
clib_container_single_linked_list_moveto_pre(
        struct clib_container_single_linked_list *list,
        struct clib_container_single_linked_list_entry *entry1,
        struct clib_container_single_linked_list_entry *entry2);


/**
 * 获取指定元素的下一个元素
 * @param entry 指定元素
 * @return
 *      成功 找到的下一个元素
 *      失败 NULL
 */
struct clib_container_single_linked_list_entry *
clib_container_single_linked_list_entry_get_next(
        struct clib_container_single_linked_list_entry *entry);


/**
 * 获取指定元素的数据指针
 * @param entry 指定元素
 * @return
 *      成功 数据指针
 *      失败 NULL
 */
void *
clib_container_single_linked_list_entry_get_data(
        struct clib_container_single_linked_list_entry *entry);

CLIB_CPLUS_SUPPORT_END

#endif //CLIB_CLIB_CONTAINER_SINGLE_LINKED_LIST_H
